/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = ora_ttc8_tti_lob.c                                 */
/*  NOTE      =                                                    */
/*  DATE      = 2015/03/16 by songbb                               */
/*******************************************************************/

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <frct_comm.h>

#include "frcomm.h"
#include "frstr.h"
#include "frmem.h"
#include "frlog.h"

#include "../../ora_core.h"
#include "../../comm/ora_comm.h"
#include "../../comm/ora_util.h"
#include "../ora_mar_engine.h"
#include "ora_ttc8_tti_lob.h"
#include "ora_ttc8_tti_lobd.h"

/*******************************************************************************
*  FUNC     :  对应于 ojdbc7_12.1.0.1 oracle.jdbc.driver.T4C8TTILob.java marshalData()
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __ora_ttc8_tti_lob_unmarshalData(Conntrack *p_st_conn
                                            , L7session_ora *p_st_sess
                                            , L7_ora_packet *p_st_ora_packet)
{
    ORA_PRINT_INFO("lob unmarshalData...\n");
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    int i = FR_NO;
    short s_ttc_code = 0;                                 // ttc code

    if ((p_st_curr_sess->c_lob_source_locator_6 & 0x80) == 128)
        i = FR_YES;

    // ttc code should be APM_TTC_CODE_TTILOBD
    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_ttc_code) != FR_SUCC)
        goto error;

    // TODO: 长连接情况下p_st_sess->s_version_number未能确定
    if (p_st_sess->s_version_number < 10101 && i != FR_NO)
    {
        if (ora_ttc8_tti_lobd_unmarshalClobUB2_For9iDB(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
            goto error;
    }
    else
    {
        if (ora_ttc8_tti_lobd_unmarshalLobData(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
            goto error;
    }

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  对应于 ojdbc7_12.1.0.1 oracle.jdbc.driver.T4C8TTILob.java marshal()
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_tti_lob_unmarshal(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    char c_tmp = 0;
    short s_tmp = 0;
    int i_tmp = 0;
    long long ll_tmp = 0LL;
    char *p_tmp = NULL;
    char c_src_lob_locator_flag = 0;
    char c_dest_lob_locator_flag = 0;
    int i_lobscnl = 0;
    int i_loop = 0;
    long long ll_lobops = 0LL;
    int i_ttc_type_rep_3_tmp = 0;

    ORA_PRINT_ALERT("i_use_oci = %s, "
                            "i_use_special_field = %s, "
                            "i_send_typerep = %s, "
                            "i_ttc8_stmt_resp_oac_skip1 = %s, "
                            "i_ptr_len = %d, "
                            "i_oci_stmt_req_skip4_ttc8 = %s, "
                            "c_ttc_version = %d, "
                            "i_ttc8_stmt_resp_dcbkm = %s, "
                            "i_ttc8_stmt_resp_dcbni1 = %s\n",
                    p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_use_oci == FR_YES ? "FR_YES" : "FR_NO"),
                    p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_use_special_field == FR_YES ? "FR_YES" : "FR_NO"),
                    p_st_sess->i_send_typerep == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_send_typerep == FR_YES ? "FR_YES" : "FR_NO"),
                    p_st_sess->i_ttc8_stmt_resp_oac_skip1 == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_oac_skip1 == FR_YES ? "FR_YES" : "FR_NO"),
                    p_st_sess->i_ptr_len,
                    p_st_sess->i_oci_stmt_req_skip4_ttc8 == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES ? "FR_YES" : "FR_NO"),
                    p_st_sess->c_ttc_version,
                    p_st_sess->i_ttc8_stmt_resp_dcbkm == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_dcbkm == FR_YES ? "FR_YES" : "FR_NO"),
                    p_st_sess->i_ttc8_stmt_resp_dcbni1 == APM_ORA_FLAG_UNSET ? "UNSET" : (p_st_sess->i_ttc8_stmt_resp_dcbni1 == FR_YES ? "FR_YES" : "FR_NO"));

    if (p_st_sess->i_use_oci == APM_ORA_FLAG_UNSET ||
            p_st_sess->i_use_special_field == APM_ORA_FLAG_UNSET ||
            (p_st_sess->i_send_typerep == APM_ORA_FLAG_UNSET && p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_ttc8_stmt_resp_oac_skip1 == APM_ORA_FLAG_UNSET) ||
            (p_st_sess->i_send_typerep == FR_NO && p_st_sess->i_ptr_len == APM_ORA_PTR_LEN_8 && p_st_sess->i_oci_stmt_req_skip4_ttc8 == APM_ORA_FLAG_UNSET) ||
            (p_st_sess->c_ttc_version == APM_ORA_FLAG_UNSET && p_st_sess->i_ttc8_stmt_resp_dcbkm == APM_ORA_FLAG_UNSET) ||
            (p_st_sess->c_ttc_version == APM_ORA_FLAG_UNSET && p_st_sess->i_ttc8_stmt_resp_dcbni1 == APM_ORA_FLAG_UNSET))
    {
        ORA_PRINT_ALERT("sess params incompele\n");
        goto error;
    }

    if ((p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_YES) || p_st_sess->i_ttc8_stmt_resp_oac_skip1 == FR_NO)
    {
        i_ttc_type_rep_3_tmp = ora_get_ttc_type_rep(p_st_sess, 3);
        ora_set_ttc_type_rep(p_st_sess, 3, 1);
    }

    if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC) // seqNumber
        goto error;

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_src_lob_locator_flag) != FR_SUCC) // PTR(sourceLobLocator is not null)
        goto error;

    if (ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &p_st_curr_sess->i_lob_source_locator_len) != FR_SUCC) // i(sourceLobLocator.length)
        goto error;
    if (c_src_lob_locator_flag == APM_ORA_NULLPTR)
        p_st_curr_sess->i_lob_source_locator_len = 0;
    ORA_PRINT_DBG("set i_lob_source_locator_len = %d\n", p_st_curr_sess->i_lob_source_locator_len);

    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after sourceLobLocator.length\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_dest_lob_locator_flag) != FR_SUCC) // PTR(destinationLobLocator is not null)
        goto error;

    if (ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &p_st_curr_sess->i_lob_destination_locator_len) != FR_SUCC) // destinationLength
        goto error;
    if (c_dest_lob_locator_flag == APM_ORA_NULLPTR)
        p_st_curr_sess->i_lob_destination_locator_len = 0;
    ORA_PRINT_DBG("set i_lob_destination_locator_len = %d\n", p_st_curr_sess->i_lob_destination_locator_len);

    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after destinationLobLocator.length\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // sourceOffset
        goto error;

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // destinationOffset
        goto error;

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &p_st_curr_sess->c_lob_characterset) != FR_SUCC) // PTR(characterSet is not 0)
        goto error;
    ORA_PRINT_DBG("set c_lob_characterset = %d\n", p_st_curr_sess->c_lob_characterset);

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &p_st_curr_sess->c_lob_send_lob_amt) != FR_SUCC) // PTR(sendLobamt is true and ttc version is less than 3)
        goto error;
    ORA_PRINT_DBG("set c_lob_send_lob_amt = %d\n", p_st_curr_sess->c_lob_send_lob_amt);

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &p_st_curr_sess->c_lob_nullO2U) != FR_SUCC) // PTR(nullO2U is true)
        goto error;
    ORA_PRINT_DBG("set c_lob_nullO2U = %d\n", p_st_curr_sess->c_lob_nullO2U);

    if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_lobops) != FR_SUCC) // lobops
        goto error;
    ORA_PRINT_DBG("ll_lobops = %lld\n", ll_lobops);

    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after lobops\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }

    if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // PTR(lobscnl is not 0)
        goto error;

    if (ora_mar_unmarshalSB4(p_st_sess, p_st_ora_packet, &i_lobscnl) != FR_SUCC) // lobscnl
        goto error;
    ORA_PRINT_DBG("i_lobscnl = %d\n", i_lobscnl);

    if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
    {
        ORA_PRINT_DBG("skip 4 bytes after lobscnl\n");
        if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
            goto error;
    }

    if (p_st_sess->c_ttc_version >= 3 || p_st_sess->i_ttc8_stmt_resp_dcbkm == FR_YES)
    {
        if (ora_mar_unmarshalSB8(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // sourceOffset
            goto error;

        if (ora_mar_unmarshalSB8(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // destinationOffset
            goto error;

        if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &p_st_curr_sess->c_lob_send_lob_amt) != FR_SUCC) // PTR(sendLobamt is true)
            goto error;
        ORA_PRINT_DBG("set c_lob_send_lob_amt = %d\n", p_st_curr_sess->c_lob_send_lob_amt);

        if (p_st_sess->c_ttc_version >= 4 || p_st_sess->i_ttc8_stmt_resp_dcbni1 == FR_YES)
        {
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // NULLPTR
                goto error;
            if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // 0
                goto error;
            if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
            {
                ORA_PRINT_DBG("skip 4 bytes after SWORD(0)\n");
                if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                    goto error;
            }
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // NULLPTR
                goto error;
            if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // 0
                goto error;
            if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
            {
                ORA_PRINT_DBG("skip 4 bytes after SWORD(0)\n");
                if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                    goto error;
            }
            if (ora_mar_unmarshalO2U(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // NULLPTR
                goto error;
            if (ora_mar_unmarshalSWORD(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // 0
                goto error;
            if (p_st_sess->i_oci_stmt_req_skip4_ttc8 == FR_YES)
            {
                ORA_PRINT_DBG("skip 4 bytes after SWORD(0)\n");
                if (ora_mar_skip(p_st_ora_packet, 4) != FR_SUCC)
                    goto error;
            }
        }
    }

    p_st_curr_sess->c_lob_source_locator_6 = 0;
    p_st_curr_sess->c_lob_source_locator_7 = 0;
    if (p_st_curr_sess->i_lob_source_locator_len > 0)
    {
        ORA_PRINT_DBG("unmarshal sourceLobLocator by length %d\n", p_st_curr_sess->i_lob_source_locator_len);
        if (ora_mar_unmarshalB1Array(p_st_curr_sess->i_lob_source_locator_len, p_st_ora_packet, &p_tmp) != FR_SUCC) // sourceLobLocator
            goto error;
        if (p_st_curr_sess->i_lob_source_locator_len > 6)
            p_st_curr_sess->c_lob_source_locator_6 = p_tmp[6];
        if (p_st_curr_sess->i_lob_source_locator_len > 7)
            p_st_curr_sess->c_lob_source_locator_7 = p_tmp[7];
        ora_free((void **) &p_tmp);
    }

    if (p_st_curr_sess->i_lob_destination_locator_len > 0)
    {
        ORA_PRINT_DBG("unmarshal destinationLobLocator\n");
        if (ora_mar_unmarshalB1Array(p_st_curr_sess->i_lob_destination_locator_len, p_st_ora_packet, &p_tmp) == FR_SUCC) // destinationLobLocator
            ora_free((void **) &p_tmp);
        else
            goto error;
    }

    if (p_st_curr_sess->c_lob_characterset != 0)
    {
        ORA_PRINT_DBG("unmarshal characterSet\n");
        if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // characterSet
            goto error;
    }

    if ((p_st_curr_sess->c_lob_send_lob_amt == APM_ORA_PTR && p_st_sess->c_ttc_version != APM_ORA_FLAG_UNSET && p_st_sess->c_ttc_version < 3) ||
            (p_st_sess->c_ttc_version == APM_ORA_FLAG_UNSET && p_st_sess->i_ttc8_stmt_resp_dcbkm == FR_NO))
    {
        ORA_PRINT_DBG("unmarshal lobamt UB4\n");
        if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // lobamt
            goto error;
    }

    if (i_lobscnl != 0)
    {
        ORA_PRINT_DBG("unmarshal lobscn:[%d]\n", i_lobscnl);
        for (i_loop = 0; i_loop < i_lobscnl; i_loop++)
        {
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // lobscn
                goto error;
        }
    }

    if (p_st_curr_sess->c_lob_send_lob_amt == APM_ORA_PTR && (p_st_sess->c_ttc_version >= 3 || p_st_sess->i_ttc8_stmt_resp_dcbkm == FR_YES))
    {
//        if ((p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_YES) || p_st_sess->i_ttc8_stmt_resp_oac_skip1 == FR_NO)
//        {
//            ORA_PRINT_DBG("unmarshal lobamt UB2\n");
//            if (ora_mar_unmarshalUB2(p_st_sess, p_st_ora_packet, &i_tmp) != FR_SUCC) // lobamt
//                goto error;
//        }
//        else
//        {

        /**
         * ./apm -n -w 5 -d ../../src/oracle/pcap/sqlplus_oci_all_v2/11.2.0.2_a_windows_gb2312/sqlplus_gb2312_192.168.18.168_11.2.0.2_a_windows_2_192.168.18.167_11.1.0.6_z.pcap
         */
            ORA_PRINT_DBG("unmarshal lobamt SB8\n");
            if (ora_mar_unmarshalSB8(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // lobamt
                goto error;
//        }
    }

    if (ll_lobops == 64L && (p_st_sess->c_ttc_version >= 3 || p_st_sess->i_ttc8_stmt_resp_dcbkm == FR_YES))
    {
        ORA_PRINT_DBG("unmarshal lob data\n");
        if (__ora_ttc8_tti_lob_unmarshalData(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
            goto error;
    }

    if ((p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_YES) || p_st_sess->i_ttc8_stmt_resp_oac_skip1 == FR_NO)
        ora_set_ttc_type_rep(p_st_sess, 3, i_ttc_type_rep_3_tmp);
    return FR_SUCC;
error:
    if ((p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_YES) || p_st_sess->i_ttc8_stmt_resp_oac_skip1 == FR_NO)
        ora_set_ttc_type_rep(p_st_sess, 3, i_ttc_type_rep_3_tmp);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  对应于 ojdbc7_12.1.0.1 oracle.jdbc.driver.T4C8TTILob.java readLOBD()
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_tti_lob_read_LOBD(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    int i = FR_NO;

    if ((p_st_curr_sess->c_lob_source_locator_6 & 0x80) == 128)
        i = FR_YES;

    // TODO: 长连接情况下p_st_sess->s_version_number未能确定
    if (p_st_sess->s_version_number < 10101 && i != FR_NO)
    {
        if (ora_ttc8_tti_lobd_unmarshalClobUB2_For9iDB(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
            goto error;
    }
    else
    {
        if (ora_ttc8_tti_lobd_unmarshalLobData(p_st_conn, p_st_sess, p_st_ora_packet) != FR_SUCC)
            goto error;
    }

    if (bytebuff_remaining(p_st_ora_packet->p_st_packet) == 0)
    {
        ora_packet_need_next_packet(p_st_ora_packet);
        goto error;
    }

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  对应于 ojdbc7_12.1.0.1 oracle.jdbc.driver.T4C8TTILob.java readRPA()
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_tti_lob_read_RPA(Conntrack *p_st_conn
                            , L7session_ora *p_st_sess
                            , L7_ora_packet *p_st_ora_packet)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    char c_tmp = 0;
    char *p_tmp = NULL;
    short s_tmp = 0;
    long long ll_tmp = 0LL;
    int i_ttc_type_rep_3_tmp = 0;
    if ((p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_YES) || p_st_sess->i_ttc8_stmt_resp_oac_skip1 == FR_NO)
    {
        i_ttc_type_rep_3_tmp = ora_get_ttc_type_rep(p_st_sess, 3);
        ora_set_ttc_type_rep(p_st_sess, 3, 1);
    }

    ORA_PRINT_DBG("i_lob_source_locator_len:[%d]\n", p_st_curr_sess->i_lob_source_locator_len);
    if (p_st_curr_sess->i_lob_source_locator_len > 0)
    {
        if (ora_mar_unmarshalNBytes_by_len(p_st_curr_sess->i_lob_source_locator_len, p_st_ora_packet, &p_tmp) == FR_SUCC) // sourceLobLocator
            ora_free((void **) &p_tmp);
        else
            goto error;
    }

    ORA_PRINT_DBG("i_lob_destination_locator_len:[%d]\n", p_st_curr_sess->i_lob_destination_locator_len);
    if (p_st_curr_sess->i_lob_destination_locator_len > 0)
    {
        if (ora_mar_unmarshalSB2(p_st_sess, p_st_ora_packet, &s_tmp) != FR_SUCC) // i
            goto error;
        if (ora_mar_skipNBytes_by_len(s_tmp, p_st_ora_packet) != FR_SUCC) // destinationLobLocator
            goto error;
    }

    ORA_PRINT_DBG("c_lob_characterset:[%d]\n", p_st_curr_sess->c_lob_characterset);
    if (p_st_curr_sess->c_lob_characterset != 0)
    {
        if (ora_mar_unmarshalSB2(p_st_sess, p_st_ora_packet, &s_tmp) != FR_SUCC) // characterSet
            goto error;
    }

    ORA_PRINT_DBG("c_lob_send_lob_amt:[%d]\n", p_st_curr_sess->c_lob_send_lob_amt);
    if (p_st_curr_sess->c_lob_send_lob_amt == APM_ORA_PTR)
    {
        if (p_st_sess->c_ttc_version >= 3 || p_st_sess->i_ttc8_stmt_resp_dcbkm == FR_YES)
        {
            ORA_PRINT_DBG("unmarshal lobamt SB8\n");
            if (ora_mar_unmarshalSB8(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // lobamt
                goto error;
        }
        else
        {
            ORA_PRINT_DBG("unmarshal lobamt UB4\n");
            if (ora_mar_unmarshalUB4(p_st_sess, p_st_ora_packet, &ll_tmp) != FR_SUCC) // lobamt
                goto error;
        }
    }

    ORA_PRINT_DBG("c_lob_nullO2U:[%d]\n", p_st_curr_sess->c_lob_nullO2U);
    if (p_st_curr_sess->c_lob_nullO2U == APM_ORA_PTR)
    {
        if (ora_mar_unmarshalSB1(p_st_sess, p_st_ora_packet, &c_tmp) != FR_SUCC) // i
            goto error;
//        if (i != 0) {
//            this.lobnull = true;
//        }
    }

    if ((p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_YES) || p_st_sess->i_ttc8_stmt_resp_oac_skip1 == FR_NO)
        ora_set_ttc_type_rep(p_st_sess, 3, i_ttc_type_rep_3_tmp);
    return FR_SUCC;
error:
    if ((p_st_sess->i_use_special_field == FR_YES && p_st_sess->i_send_typerep == FR_YES) || p_st_sess->i_ttc8_stmt_resp_oac_skip1 == FR_NO)
        ora_set_ttc_type_rep(p_st_sess, 3, i_ttc_type_rep_3_tmp);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  设置RPC函数指针
*  ARGS     :  *p_st_ora_rpc_recv  (函数指针结构体)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void ora_tti_lob_set_rpc_func(Ora_rpc_recv *p_st_ora_rpc_recv)
{
    p_st_ora_rpc_recv->read_LOBD = &ora_ttc8_tti_lob_read_LOBD;
    p_st_ora_rpc_recv->read_RPA = &ora_ttc8_tti_lob_read_RPA;
    return;
}
